package cn.cdu.doctor.controller;

import cn.cdu.basics.baseVo.PageVo;
import cn.cdu.basics.baseVo.Result;
import cn.cdu.basics.lock.RedisLockConfig;
import cn.cdu.basics.utils.PageUtil;
import cn.cdu.basics.utils.ResultUtil;
import cn.cdu.basics.utils.SecurityUtil;
import cn.cdu.data.entity.User;
import cn.cdu.data.utils.NullUtils;
import cn.cdu.doctor.entity.Doctor;
import cn.cdu.doctor.entity.DoctorScheduling;
import cn.cdu.doctor.entity.HospitalOrder;
import cn.cdu.doctor.service.IDoctorSchedulingService;
import cn.cdu.doctor.service.IDoctorService;
import cn.cdu.doctor.service.IHospitalOrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.*;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.locks.Lock;

import static cn.cdu.basics.parameter.SettingConstant.DOCTOR_ORDER_KEY;


@RestController
@Api(tags = "挂号管理接口")
@RequestMapping("/zwz/hospitalOrder")
@Transactional
public class HospitalOrderController {

    @Autowired
    private IHospitalOrderService iHospitalOrderService;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private IDoctorService iDoctorService;

    @Autowired
    private IDoctorSchedulingService iDoctorSchedulingService;

    @Resource
    private RedisLockRegistry redisLockRegistry;

    @RequestMapping(value = "/getMyOrderList", method = RequestMethod.POST)
    @ApiOperation(value = "查询我的挂号")
    public Result<IPage<HospitalOrder>> getMyOrderList(@RequestBody PageVo page) {
        User currUser = securityUtil.getCurrUser();
        QueryWrapper<HospitalOrder> qw = new QueryWrapper<>();
        qw.eq("user_id", currUser.getId());
        qw.orderByDesc("create_time");
        return new ResultUtil<IPage<HospitalOrder>>().setData(iHospitalOrderService.page(PageUtil.initMpPage(page), qw));
    }

    @RequestMapping(value = "/payMoney", method = RequestMethod.POST)
    @ApiOperation(value = "挂号付款")
    public Result<Object> payMoney(@RequestParam String orderId) {
        HospitalOrder ho = iHospitalOrderService.getById(orderId);
        if (ho == null) {
            return ResultUtil.error("挂号单不存在");
        }
        ho.setMoneyFlag(1);
        iHospitalOrderService.saveOrUpdate(ho);
        return ResultUtil.success("付款成功");
    }

    @RequestMapping(value = "/noneOrder", method = RequestMethod.POST)
    @ApiOperation(value = "取消挂号")
    public Result<Object> noneOrder(@RequestParam String orderId) {
        HospitalOrder ho = iHospitalOrderService.getById(orderId);
        if (ho == null) {
            return new ResultUtil<Object>().setErrorMsg("挂号单不存在");
        }
        ho.setStatus(1);
        iHospitalOrderService.saveOrUpdate(ho);
        return ResultUtil.success("取消成功");
    }

    @RequestMapping(value = "/addOrder", method = RequestMethod.POST)
    @ApiOperation(value = "新增挂号")
    public Result<Object> addOrder(@RequestParam String orderId) throws Exception {

        // 获取锁
        Lock lock = redisLockRegistry.obtain(DOCTOR_ORDER_KEY);
        lock.lock();
        try {
            User currUser = securityUtil.getCurrUser();
            DoctorScheduling ds = iDoctorSchedulingService.getById(orderId);
            if (ds == null) {
                return ResultUtil.error("号源不存在");
            }
            if (ds.getOrderFlag() > 0) {
                return ResultUtil.error("您手慢啦,该号已被别人预约!");
            }
            Doctor doctor = iDoctorService.getById(ds.getDoctorId());
            if (doctor == null) {
                return ResultUtil.error("医生不存在");
            }
            ds.setOrderFlag(1);
            iDoctorSchedulingService.saveOrUpdate(ds);
            HospitalOrder ho = new HospitalOrder();
            ho.setUserId(currUser.getId());
            ho.setUserName(currUser.getNickname());
            ho.setOrderId(ds.getId());
            ho.setNumber(ds.getNumber());
            ho.setStep(ds.getStep());
            ho.setDateTime(ds.getDate());
            ho.setDoctorId(ds.getDoctorId());
            ho.setDoctorName(ds.getDoctorName());
            ho.setMoneyData(doctor.getOrderMoney());
            iHospitalOrderService.saveOrUpdate(ho);

        } catch (Exception e) {
            throw new Exception("新增挂号失败 - " + e.getMessage());
        } finally {
            // 配合解锁逻辑
            lock.unlock();
        }
        return ResultUtil.success("预约成功!");
    }

    @RequestMapping(value = "/getAll", method = RequestMethod.GET)
    @ApiOperation(value = "查询所有挂号信息")
    public Result<List<HospitalOrder>> getAll() {
        return new ResultUtil<List<HospitalOrder>>().setData(iHospitalOrderService.list());
    }

    @RequestMapping(value = "/getByPage", method = RequestMethod.GET)
    @ApiOperation(value = "查询挂号信息")
    public Result<IPage<HospitalOrder>> getByPage(PageVo page) {
        return new ResultUtil<IPage<HospitalOrder>>().setData(iHospitalOrderService.page(PageUtil.initMpPage(page)));
    }

    @RequestMapping(value = "/insertOrUpdate", method = RequestMethod.POST)
    @ApiOperation(value = "增改挂号信息")
    public Result<HospitalOrder> saveOrUpdate(HospitalOrder hospitalOrder) {
        if (iHospitalOrderService.saveOrUpdate(hospitalOrder)) {
            return new ResultUtil<HospitalOrder>().setData(hospitalOrder);
        }
        return ResultUtil.error();
    }

    @RequestMapping(value = "/delByIds", method = RequestMethod.POST)
    @ApiOperation(value = "删除挂号信息")
    public Result<Object> delAllByIds(@RequestParam String[] ids) {
        for (String id : ids) {
            iHospitalOrderService.removeById(id);
        }
        return ResultUtil.success();
    }

    @ApiOperation(value = "根据患者ID获取最新挂号单")
    @GetMapping("/getLatestByPatientId")
    public Result<HospitalOrder> getLatestByPatientId(@RequestParam String patientId) {
        QueryWrapper<HospitalOrder> qw = new QueryWrapper<>();
        qw.eq("user_id", patientId);
        qw.eq("del_flag", 0);
        qw.eq("status", 0);
        qw.orderByDesc("create_time");
        qw.last("LIMIT 1");
        HospitalOrder order = iHospitalOrderService.getOne(qw);
        if (order == null) {
            return ResultUtil.error("未找到该患者的挂号记录");
        }
        return new ResultUtil<HospitalOrder>().setData(order);
    }
}
